package view.panel;

import dao.CommodityDAO;
import dao.CategoryDAO;
import tool.DisableEditTableModel;
import view.dialog.CategoryDialog;

import javax.swing.*;

import bean.Commodity;
import bean.Category;

import java.awt.*;
import java.awt.event.*;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.Vector;

public class CommodityPanel extends JPanel {
    private static final long serialVersionUID = -3642008193250417745L;
    private CategoryDAO commodityTypeDAO;
    private CommodityDAO commodityDAO;
    private Dimension dimension;
    private Hashtable<Integer, String> commodityTypeData;
    private Set<Map.Entry<Integer, String>> categoriesDataEntrySet;
    private JPanel leftPanel;
    private JPanel northPanel;
    private JTextField queryIdTextField;
    private JTextField queryKeywordTextField;
    private JComboBox<String> queryCategoryComboBox;
    private DefaultComboBoxModel<String> queryComboBoxModel;
    private JButton queryButton;
    private JScrollPane scrollPane;
    private JTable table;
    private DisableEditTableModel tableModel;
    private Vector<String> columnNames;
    private JPanel southPanel;
    private JButton editCommodityButton;
    private JButton addCommodityButton;
    private JButton deleteCommodityButton;
    private JPanel rightPanel;
    private JPanel panel1, panel2, panel3, panel4, panel5, panel6, panel7;
    private JTextField commodityIdTextField;
    private JTextField commodityNameTextField;
    private JComboBox<String> categoriesComboBox;
    private DefaultComboBoxModel<String> comboBoxModel;
    private JTextField costPriceTextField;
    private JTextField salePriceTextField;
    private JTextField addCommodityQuantityTextField;
    private JButton submitButton;
    private JButton manageCategoriesButton;

    public CommodityPanel(Connection conn) throws SQLException {
        super(new BorderLayout());
        commodityTypeDAO = new CategoryDAO(conn);
        commodityDAO = new CommodityDAO(conn);
        setName("商品管理");
        dimension = new Dimension(83, 22);
        comboBoxItems();
        leftPanel = new JPanel(new BorderLayout());
        leftPanel.add(new JPanel(), BorderLayout.NORTH);
        northPanel = (JPanel) leftPanel.getComponent(0);
        northPanel.add(new JLabel("商品编号"));
        queryIdTextField = new JTextField();
        queryIdTextField.setPreferredSize(dimension);
        queryIdTextField.addFocusListener(new FocusListener() {
            @Override
            public void focusGained(FocusEvent focusEvent) {}

            @Override
            public void focusLost(FocusEvent focusEvent) {
                JTextField source = (JTextField) focusEvent.getComponent();
                String commodityIdText = source.getText();
                if (Objects.nonNull(commodityIdText) && commodityIdText.length() > 0) {
                    queryKeywordTextField.setText(null);
                    queryCategoryComboBox.setSelectedIndex(0);
                }
            }
        });
        northPanel.add(queryIdTextField);
        northPanel.add(new JLabel("商品关键字"));
        queryKeywordTextField = new JTextField();
        queryKeywordTextField.setPreferredSize(dimension);
        queryKeywordTextField.addFocusListener(new FocusListener() {
            @Override
            public void focusGained(FocusEvent focusEvent) {}

            @Override
            public void focusLost(FocusEvent focusEvent) {
                JTextField source = (JTextField) focusEvent.getComponent();
                String commodityKeywordText = source.getText();
                if (Objects.nonNull(commodityKeywordText) && commodityKeywordText.length() > 0) {
                    queryIdTextField.setText(null);
                }
            }
        });
        northPanel.add(queryKeywordTextField);
        northPanel.add(new JLabel("商品类别"));
        queryCategoryComboBox = new JComboBox<>();
        queryCategoryComboBox.setPreferredSize(dimension);
        queryCategoryComboBox.addItemListener(itemEvent -> {
            if (itemEvent.getStateChange() == ItemEvent.SELECTED) {
                queryIdTextField.setText(null);
            }
        });
        northPanel.add(queryCategoryComboBox);
        queryButton = new JButton("查询商品");
        queryButton.addActionListener(actionEvent -> {
            String queryId = queryIdTextField.getText();
            try {
                int categoryId = 0;
                // 通过商品编号查询
                if (Objects.nonNull(queryId) && queryId.length() > 0) {
                    int commodityId = Integer.parseInt(queryId);
                    tableModel.setDataVector(getRowsData(commodityId), columnNames());
                    // 通过商品关键字及所属商品类别查询
                } else {
                    String keyWord = queryKeywordTextField.getText();
                    String categoryName = (String) queryCategoryComboBox.getSelectedItem();
                    for (Map.Entry<Integer, String> entry : categoriesDataEntrySet) {
                        if (entry.getValue().equals(categoryName)) {
                            categoryId = entry.getKey();
                            break;
                        }
                    }
                    tableModel.setDataVector(getRowsData(keyWord, categoryId), columnNames());
                }
                String commodityId = commodityIdTextField.getText();
                if (Objects.nonNull(commodityId) && commodityId.length() > 0) {
                    commodityIdTextField.setText(null);
                    commodityNameTextField.setText(null);
                    costPriceTextField.setText(null);
                    salePriceTextField.setText(null);
                    addCommodityQuantityTextField.setText(null);
                }
                if (queryCategoryComboBox.getSelectedIndex() == 0) {
                    comboBoxItems();
                    addItemsToComboBoxes();
                }
            } catch (NumberFormatException e) {
                JOptionPane.showMessageDialog(null, "商品编号不是纯数字");
                queryIdTextField.requestFocusInWindow();
                queryIdTextField.selectAll();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        });
        northPanel.add(queryButton);
        scrollPane = new JScrollPane();
        table = new JTable();
        tableModel = new DisableEditTableModel();
        tableModel.setDataVector(getRowsData(null, 0), columnNames());
        table.setModel(tableModel);
        scrollPane.setViewportView(table);
        leftPanel.add(scrollPane, BorderLayout.CENTER);
        southPanel = new JPanel();
        editCommodityButton = new JButton("编辑商品");
        editCommodityButton.addActionListener(actionEvent -> {
            int length = table.getSelectedRows().length;
            if (length == 1) {
                int rowIndex = table.getSelectedRow();
                int commodityId = (int) tableModel.getValueAt(rowIndex, 0);
                try {
                    commodityIdTextField.setText(String.valueOf(commodityId));
                    Commodity commodity = commodityDAO.selectById(commodityId);
                    commodityNameTextField.setText(commodity.getCommodityName());
                    String categoryName = null;
                    for (Map.Entry<Integer, String> entry : categoriesDataEntrySet) {
                        if (entry.getKey().equals(commodity.getCategoryId())) {
                            categoryName = entry.getValue();
                            break;
                        }
                    }
                    categoriesComboBox.setSelectedItem(categoryName);
                    costPriceTextField.setText(String.valueOf(commodity.getCostPrice()));
                    salePriceTextField.setText(String.valueOf(commodity.getSalePrice()));
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        });
        southPanel.add(editCommodityButton);
        addCommodityButton = new JButton("添加商品");
        addCommodityButton.addActionListener(actionEvent -> {
            commodityIdTextField.setText(null);
            commodityNameTextField.setText(null);
            costPriceTextField.setText(null);
            salePriceTextField.setText(null);
            addCommodityQuantityTextField.setText(null);
            table.clearSelection();
        });
        southPanel.add(addCommodityButton);
        deleteCommodityButton = new JButton("删除商品");
        deleteCommodityButton.addActionListener(actionEvent -> {
            int[] rows = table.getSelectedRows();
            try {
                if (rows.length > 0) {
                    int state = JOptionPane.showConfirmDialog(null, "确定要删除选中的商品信息吗？此操作不可逆。", "确认删除", JOptionPane.YES_NO_OPTION);
                    if (state == 0) {
                        JPanel cardPanel = (JPanel) getParent();
                        BillPanel billPanel = (BillPanel) cardPanel.getComponent(0);
                        JScrollPane scrollPane = (JScrollPane) billPanel.getComponent(0);
                        JTable table = (JTable) scrollPane.getViewport().getView();
                        DisableEditTableModel tableModel = (DisableEditTableModel) table.getModel();
                        boolean flag = true;
                        if (tableModel.getRowCount() > 0) {
                            // 倒序删除商品
                            for (int rowIndex = rows.length - 1; rowIndex > -1; rowIndex--) {
                                int commodityId = (int) this.tableModel.getValueAt(rows[rowIndex], 0);
                                for (int index = tableModel.getRowCount() - 1; index > -1; index--) {
                                    int id = (int) tableModel.getValueAt(index, 0);
                                    if (commodityId == id) {
                                        if (flag) {
                                            flag = false;
                                        }
                                        state = 0;
                                        break;
                                    } else {
                                        state = 1;
                                    }
                                }
                                if (state == 1) {
                                    // 先从数据库表中删除指定商品
                                    commodityDAO.delete(commodityId);
                                    // 再从商品界面的表格模型中删除指定行
                                    this.tableModel.removeRow(rows[rowIndex]);
                                }
                            }
                        } else {
                            // 倒序删除商品
                            for (int rowIndex = rows.length - 1; rowIndex > -1; rowIndex--) {
                                int commodityId = (int) this.tableModel.getValueAt(rows[rowIndex], 0);
                                commodityDAO.delete(commodityId);
                                this.tableModel.removeRow(rows[rowIndex]);
                            }
                        }
                        if (flag) {
                            JOptionPane.showMessageDialog(null, "指定商品信息删除成功");
                        } else {
                            JOptionPane.showMessageDialog(null, "一个或更多的商品已被添加至购物车内。不能删除这类商品信息");
                        }
                        String commodityId = commodityIdTextField.getText();
                        if (Objects.nonNull(commodityId) && commodityId.length() > 0) {
                            commodityIdTextField.setText(null);
                            commodityNameTextField.setText(null);
                            costPriceTextField.setText(null);
                            salePriceTextField.setText(null);
                            addCommodityQuantityTextField.setText(null);
                        }
                    }
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        });
        southPanel.add(deleteCommodityButton);
        leftPanel.add(southPanel, BorderLayout.SOUTH);
        add(leftPanel, BorderLayout.CENTER);
        rightPanel = new JPanel(new GridLayout(7, 1));
        add(rightPanel, BorderLayout.EAST);
        rightPanel.add(new JPanel());
        panel1 = (JPanel) rightPanel.getComponent(0);
        panel1.add(new JLabel("商品编号"));
        commodityIdTextField = new JTextField();
        commodityIdTextField.setPreferredSize(dimension);
        commodityIdTextField.setEnabled(false);
        panel1.add(commodityIdTextField);
        rightPanel.add(new JPanel());
        panel2 = (JPanel) rightPanel.getComponent(1);
        panel2.add(new JLabel("商品名称"));
        commodityNameTextField = new JTextField();
        commodityNameTextField.setPreferredSize(dimension);
        panel2.add(commodityNameTextField);
        rightPanel.add(new JPanel());
        panel3 = (JPanel) rightPanel.getComponent(2);
        panel3.add(new JLabel("商品类别名称"));
        categoriesComboBox = new JComboBox<>();
        categoriesComboBox.setPreferredSize(dimension);
        panel3.add(categoriesComboBox);
        rightPanel.add(new JPanel());
        panel4 = (JPanel) rightPanel.getComponent(3);
        panel4.add(new JLabel("商品成本价格"));
        costPriceTextField = new JTextField();
        costPriceTextField.setPreferredSize(dimension);
        panel4.add(costPriceTextField);
        rightPanel.add(new JPanel());
        panel5 = (JPanel) rightPanel.getComponent(4);
        panel5.add(new JLabel("商品价格"));
        salePriceTextField = new JTextField();
        salePriceTextField.setPreferredSize(dimension);
        panel5.add(salePriceTextField);
        rightPanel.add(new JPanel());
        panel6 = (JPanel) rightPanel.getComponent(5);
        panel6.add(new JLabel("添加商品数量"));
        addCommodityQuantityTextField = new JTextField();
        addCommodityQuantityTextField.setPreferredSize(dimension);
        panel6.add(addCommodityQuantityTextField);
        rightPanel.add(new JPanel());
        panel7 = (JPanel) rightPanel.getComponent(6);
        submitButton = new JButton("提交");
        submitButton.addActionListener(actionEvent -> {
            try {
                String commodityIdText = commodityIdTextField.getText();
                String commodityName = commodityNameTextField.getText();
                String categoryName = (String) categoriesComboBox.getSelectedItem();
                int categoryId = 0;
                for (Map.Entry<Integer, String> entry : categoriesDataEntrySet) {
                    if (entry.getValue().equals(categoryName)) {
                        categoryId = entry.getKey();
                        break;
                    }
                }
                BigDecimal costPrice = new BigDecimal(costPriceTextField.getText());
                BigDecimal salePrice = new BigDecimal(salePriceTextField.getText());
                int quantity = Integer.parseInt(addCommodityQuantityTextField.getText());
                boolean commodityNameState = Objects.nonNull(commodityName) && commodityName.length() > 0;
                boolean categoryIdState = categoryId > 0;
                boolean costPriceState = costPrice.compareTo(BigDecimal.ZERO) > 0;
                boolean salePriceState = salePrice.compareTo(BigDecimal.ZERO) > 0;
                boolean quantityState = quantity > 0;
                boolean state = commodityNameState && categoryIdState && costPriceState && salePriceState && quantityState;
                Commodity commodity = new Commodity(commodityName, categoryId, costPrice, salePrice, quantity);
                if (!state) {
                    JOptionPane.showMessageDialog(null, "商品信息不合规范，请重新编辑");
                } else if (Objects.nonNull(commodityIdText) && commodityIdText.length() > 0) {
                    // 编辑商品
                    int commodityId = Integer.parseInt(commodityIdTextField.getText());
                    commodity.setCommodityId(commodityId);
                    state = commodityDAO.update(commodity);
                    if (state) {
                        JOptionPane.showMessageDialog(null, "编辑商品信息成功");
                        commodityIdTextField.setText(null);
                    } else {
                        JOptionPane.showMessageDialog(null, "编辑商品信息失败");
                    }
                } else {
                    // 添加商品
                    state = commodityDAO.insert(commodity);
                    if (state) {
                        JOptionPane.showMessageDialog(null, "添加商品信息成功");
                    } else {
                        JOptionPane.showMessageDialog(null, "添加商品信息失败");
                    }
                }
                if (state) {
                    comboBoxItems();
                    addItemsToComboBoxes();
                    queryIdTextField.setText(null);
                    queryKeywordTextField.setText(null);
                    queryCategoryComboBox.setSelectedIndex(0);
                    tableModel.setDataVector(getRowsData(null, 0), columnNames());
                    commodityNameTextField.setText(null);
                    costPriceTextField.setText(null);
                    salePriceTextField.setText(null);
                    addCommodityQuantityTextField.setText(null);
                }
            } catch (NumberFormatException e) {
                JOptionPane.showMessageDialog(null, "商品价格或商品数量不是纯数字");
            } catch (SQLException e) {
                e.printStackTrace();
            }
        });
        panel7.add(submitButton);
        manageCategoriesButton = new JButton("管理商品类别");
        manageCategoriesButton.addActionListener(actionEvent -> {
            try {
                CategoryDialog dialog = new CategoryDialog(conn);
                dialog.setVisible(true);
                dialog.addWindowListener(new WindowAdapter() {
                    @Override
                    public void windowClosed(WindowEvent windowEvent) {
                        try {
                            comboBoxItems();
                            addItemsToComboBoxes();
                        } catch (SQLException e) {
                            e.printStackTrace();
                        }
                    }
                });
            } catch (SQLException | ClassNotFoundException e) {
                e.printStackTrace();
            }
        });
        panel7.add(manageCategoriesButton);
        addItemsToComboBoxes();
    }

    private Vector<String> comboBoxItems() throws SQLException {
        commodityTypeData = new Hashtable<>();
        Vector<Category> categories = commodityTypeDAO.selectAll();
        for (Category category : categories) {
            int categoryId = category.getCategoryId();
            String categoryName = category.getCategoryName();
            commodityTypeData.put(categoryId, categoryName);
        }
        Vector<String> items = new Vector<>();
        categoriesDataEntrySet = commodityTypeData.entrySet();
        for (Map.Entry<Integer, String> entry : categoriesDataEntrySet) {
            String categoryName = entry.getValue();
            items.addElement(categoryName);
        }
        return items;
    }

    private void addItemsToComboBoxes() throws SQLException {
        comboBoxModel = new DefaultComboBoxModel<>(comboBoxItems());
        categoriesComboBox.setModel(comboBoxModel);
        Vector<String> items = comboBoxItems();
        items.add(0, "未指定");
        queryComboBoxModel = new DefaultComboBoxModel<>(items);
        queryCategoryComboBox.setModel(queryComboBoxModel);
    }

    private Vector<String> columnNames() {
        columnNames = new Vector<>();
        columnNames.addElement("商品编号");
        columnNames.addElement("商品名称");
        columnNames.addElement("商品类别");
        columnNames.addElement("商品平均成本价格");
        columnNames.addElement("商品价格");
        columnNames.addElement("商品数量");
        return columnNames;
    }

    private Vector<Vector<Object>> getRowsData(int commodityId) throws SQLException {
        Commodity commodity = commodityDAO.selectById(commodityId);
        Vector<Vector<Object>> rowsData = new Vector<>();
        if (Objects.nonNull(commodity)) {
            addRowToRows(rowsData, commodity);
        }
        return rowsData;
    }

    private Vector<Vector<Object>> getRowsData(String keyword, int categoryId) throws SQLException {
        Vector<Commodity> commodities = commodityDAO.selectByKeyword(keyword, categoryId);
        Vector<Vector<Object>> rowsData = new Vector<>();
        for (Commodity commodity : commodities)
            addRowToRows(rowsData, commodity);
        return rowsData;
    }

    private void addRowToRows(Vector<Vector<Object>> rowsData, Commodity commodity) {
        Vector<Object> rowData = new Vector<>();
        rowData.addElement(commodity.getCommodityId());
        rowData.addElement(commodity.getCommodityName());
        rowData.addElement(commodity.getCategoryName());
        rowData.addElement(commodity.getCostPrice());
        rowData.addElement(commodity.getSalePrice());
        rowData.addElement(commodity.getQuantity());
        rowsData.addElement(rowData);
    }
}
